﻿using Microsoft.Web.WebView2.WinForms;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WinApp.Models;

namespace WinApp.Pages
{
    public partial class PageRunner : UIPage
    {
        private WebView2 _webView2;
        private RunnerQueue<ActionBase> _actionsToRun;
        public PageRunner(WebView2 webView2 = null)
        {
            _webView2 = webView2;
            _actionsToRun = new RunnerQueue<ActionBase>();
            _actionsToRun.Enqueued += ActionEnqueued;
            _actionsToRun.Dequeued += ActionDequeued;
            InitializeComponent();
            dgvRunnerQueue.AutoGenerateColumns = false;
        }

        private void ActionEnqueued(object? sender, ActionBase e)
        {
            if (_actionsToRun.Count > 0)
            {                
                dgvRunnerQueue.DataSource = _actionsToRun.Actions;
                uiTitlePanel1.Text = $"运行队列（{_actionsToRun.Count}）";
            }
            else
            {
                uiTitlePanel1.Text = "运行队列";
            }
        }

        private void ActionDequeued(object? sender, ActionBase e)
        {
            RunQueueAction();
        }

        private async void RunQueueAction()
        {
            if (_actionsToRun.Count > 0)
            {                
                dgvRunnerQueue.DataSource = _actionsToRun.Actions;
                uiTitlePanel1.Text = $"运行队列（{_actionsToRun.Count}）";
                lvRunInfo.Items.Clear();
                ActionBase action = _actionsToRun.Peek();
                action.WebView = _webView2;
                action.Completed += (c, rst) =>
                {
                    DateTime time = DateTime.Now;
                    ListViewItem lvi = new ListViewItem(time.ToString("HH:MM:ss"));
                    lvi.SubItems.Add(rst.Descprition);
                    lvi.SubItems.Add(rst.IsSuccess ? "👍" : "💥");
                    lvRunInfo.Items.Add(lvi);
                    lvRunInfo.EnsureVisible(lvRunInfo.Items.Count - 1);
                };
                DateTime time = DateTime.Now;
                ListViewItem lvi = new ListViewItem(time.ToString("HH:MM:ss"));
                lvi.SubItems.Add(action.Name);
                lvi.SubItems.Add("🚀");
                lvRunInfo.Items.Add(lvi);
                lvRunInfo.EnsureVisible(lvRunInfo.Items.Count - 1);

                ActionResult result = await action.ExecuteAsync();

                time = DateTime.Now;
                lvi = new ListViewItem(time.ToString("HH:MM:ss"));
                lvi.SubItems.Add(action.Name);
                lvi.SubItems.Add("🏁");
                lvRunInfo.Items.Add(lvi);
                lvRunInfo.EnsureVisible(lvRunInfo.Items.Count - 1);
                if (_isRunning)
                {
                    _actionsToRun.Dequeue();
                }
                else
                {
                    btnRun.Symbol = 361515;
                }
            }
            else
            {
                dgvRunnerQueue.DataSource = null;
                btnRun.Symbol = 361515;
                uiTitlePanel1.Text = "运行队列";
            }
        }

        public void AddToRun(ActionBase action)
        {
            _actionsToRun.Enqueue(action);
        }

        private bool _isRunning = false;

        private void btnRun_Click(object sender, EventArgs e)
        {
            if (_isRunning)
            {                
                _isRunning = false;
                btnRun.Symbol = 361516;
            }
            else
            {
                lvRunInfo.Items.Clear();
                RunQueueAction();
                btnRun.Symbol = 361517;
                _isRunning = true;
            }
        }
    }

    public class RunnerQueue<ActionBase>
    {
        private Queue<ActionBase> _actionsToRun = new Queue<ActionBase>();
        public event EventHandler<ActionBase> Enqueued;
        public event EventHandler<ActionBase> Dequeued;
        public void Enqueue(ActionBase action)
        {
            _actionsToRun.Enqueue(action);
            OnEnqueued(action);
        }

        public ActionBase Dequeue()
        {
            ActionBase action = _actionsToRun.Dequeue();
            Dequeued?.Invoke(this, action);
            return action;
        }

        public List<ActionBase> Actions
        {
            get
            {
                return new List<ActionBase>(_actionsToRun);
            }
        }

        public ActionBase Peek()
        {
            return _actionsToRun.Peek();
        }

        public int Count
        {
            get
            {
                return _actionsToRun.Count;
            }
        }

        protected void OnEnqueued(ActionBase e)
        {
            Enqueued?.Invoke(this, e);
        }

        protected void OnDequeued(ActionBase e)
        {
            Dequeued?.Invoke(this, e);
        }
    }
}
